//
//  NoteDAO.m
//  PersistenceLayer
//
//  Created by 马滕亚 on 2020/5/24.
//  Copyright © 2020 M.Y.A. All rights reserved.
//

#import "NoteDAO.h"

@implementation NoteDAO

+ (NoteDAO *)shareManager {
    static NoteDAO *shareManager = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        shareManager = [[self alloc] init];
    });
    return shareManager;
}

- (NSString *)applicationDocumentsDiretoryFile {
    NSString *documentDirectory = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *path = [documentDirectory stringByAppendingPathComponent:DBFILE_NAME];
    return path;
}
- (void)createEditableCopyOfDatabaseIfNeeded {
    NSString *writableDBPath = [self applicationDocumentsDiretoryFile];
    const char* cpath = [writableDBPath UTF8String];
    
    if (sqlite3_open(cpath, &db) != SQLITE_OK) {
        sqlite3_close(db);
        NSAssert(NO, @"数据库打开失败。");
    } else {
        char *err;
        NSString *sql = [NSString stringWithFormat:@"CREATE TABLE IF NOT EXISTS Note(cdata TEXT PRIMARY KEY, content TEXT);"];
        const char* cSql =[sql UTF8String];
        if (sqlite3_exec(db, cSql, NULL, NULL, &err) != SQLITE_OK) {
            sqlite3_close(db);
            NSAssert(NO, @"建表失败");
        }
        sqlite3_close(db);
    }
}

/// 插入备忘录的方法
- (int)create:(Note *)model {
    NSString *path = [self applicationDocumentsDiretoryFile];
    const char* cpath = [path UTF8String];
    if (sqlite3_open(cpath, &db) != SQLITE_OK) {
        sqlite3_close(db);
        NSAssert(NO, @"数据库打开失败。");
    } else {
        NSString *sql = @"INSERT OR REPLACE INTO note(cdata,content) VALUES(?,?)";
        const char* cSql = [sql UTF8String];
        sqlite3_stmt *statement;
        // 预处理
        if (sqlite3_prepare_v2(db, cSql, -1, &statement, NULL) == SQLITE_OK) {
            
            // 准备参数
            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
            NSString *dateStr = [dateFormatter dateFromString:model.date];
            const char* cDate = [dateStr UTF8String];
            
            const char* content = [model.content UTF8String];
            
            // 绑定参数开始
            sqlite3_bind_text(statement, 1, cDate, -1, NULL);
            sqlite3_bind_text(statement, 1, content, -1, NULL);
            
            // 执行插入
            if (sqlite3_step(statement) != SQLITE_DONE) {
                NSAssert(NO, @"插入数据失败");
            }
        }
    }
    return 0;
}

/// 删除备忘录方法
- (int)remove:(Note *)model {
    
    NSString *path = [self applicationDocumentsDiretoryFile];
    const char* cpath = [path UTF8String];
    if (sqlite3_open(cpath, &db) != SQLITE_OK) {
        sqlite3_close(db);
        NSAssert(NO, @"数据库打开失败。");
    } else {
        NSString *sql = @"DELETE from note where cdate=?";
        const char* cSql = [sql UTF8String];
        
        sqlite3_stmt *statement;
        // 预处理
        if (sqlite3_prepare_v2(db, cSql, -1, &statement, NULL) == SQLITE_OK) {
            
            // 准备参数
            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
            NSString *dateStr = [dateFormatter dateFromString:model.date];
            const char* cDate = [dateStr UTF8String];
                    
            // 绑定参数开始
            sqlite3_bind_text(statement, 1, cDate, -1, NULL);
            
            // 执行插入
            if (sqlite3_step(statement) != SQLITE_DONE) {
                NSAssert(NO, @"删除数据失败");
            }
        }
    }
    return 0;
}
/// 修改备忘录方法
- (int)modify:(Note *)model {
    NSString *path = [self applicationDocumentsDiretoryFile];
    const char* cpath = [path UTF8String];
    if (sqlite3_open(cpath, &db) != SQLITE_OK) {
        sqlite3_close(db);
        NSAssert(NO, @"数据库打开失败。");
    } else {
        NSString *sql = @"UPDATE note set content=? where cdata =?";
        const char* cSql = [sql UTF8String];
        
        sqlite3_stmt *statement;
        // 预处理
        if (sqlite3_prepare_v2(db, cSql, -1, &statement, NULL) == SQLITE_OK) {
            
            // 准备参数
            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
            NSString *dateStr = [dateFormatter dateFromString:model.date];
            const char* cDate = [dateStr UTF8String];
            
            const char* content = [model.content UTF8String];
            
            // 绑定参数开始
            sqlite3_bind_text(statement, 1, cDate, -1, NULL);
            sqlite3_bind_text(statement, 1, content, -1, NULL);
            
            // 执行插入
            if (sqlite3_step(statement) != SQLITE_DONE) {
                NSAssert(NO, @"修改数据失败");
            }
        }
    }
    return 0;
}


/// 查询所有数据方法
- (NSMutableArray *)findAll {
    NSMutableArray *listdata = [NSMutableArray array];
    
    NSString *path = [self applicationDocumentsDiretoryFile];
    const char* cpath = [path UTF8String];
    if (sqlite3_open(cpath, &db) != SQLITE_OK) {
        sqlite3_close(db);
        NSAssert(NO, @"数据库打开失败。");
    } else {
        NSString *sql = @"SELECT cdata,content FROM Note";
        const char* cSql = [sql UTF8String];
        sqlite3_stmt *statement;
        
        // 预处理
        if (sqlite3_prepare_v2(db, cSql, -1, &statement, NULL) == SQLITE_OK) {
            // 准备参数
            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
            
            // 执行
            while (sqlite3_step(statement) == SQLITE_ROW) {
                char *bufDate = (char *)sqlite3_column_text(statement, 0);
                NSString *strDate = [[NSString alloc] initWithUTF8String:bufDate];
                NSDate *date = [dateFormatter dateFromString:strDate];
                char *buffContent = (char *)sqlite3_column_text(statement, 1);
                NSString *strContent = [[NSString alloc] initWithUTF8String:buffContent];
                Note *note = [[Note alloc] initWithDate:date content:strContent];
                [listdata addObject:note];
                
                return note;
            }
        }
        // sqlite3_finalize sqlite3_close函数 释放资源
        sqlite3_finalize(statement);
        sqlite3_close(db);
    }
    return listdata;
}

/// 按照主键查询数据的方法
- (Note *)findById:(Note *)model {
    NSString *path = [self applicationDocumentsDiretoryFile];
    const char* cpath = [path UTF8String];
    if (sqlite3_open(cpath, &db) != SQLITE_OK) {
        sqlite3_close(db);
        NSAssert(NO, @"数据库打开失败。");
    } else {
        NSString *sql = @"SELECT cdata,content FROM Note where cdata =?";
        const char* cSql = [sql UTF8String];
        sqlite3_stmt *statement;
        // 预处理
        if (sqlite3_prepare_v2(db, cSql, -1, &statement, NULL) == SQLITE_OK) {
            // 准备参数
            NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
            [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss"];
            NSString *dateStr = [dateFormatter dateFromString:model.date];
            const char* cDate = [dateStr UTF8String];
            
            // 绑定参数开始
            sqlite3_bind_text(statement, 1, cDate, -1, NULL);
            
            // 执行
            if (sqlite3_step(statement) == SQLITE_OK) {
                char *bufDate = (char *)sqlite3_column_text(statement, 0);
                NSString *strDate = [[NSString alloc] initWithUTF8String:bufDate];
                NSDate *date = [dateFormatter dateFromString:strDate];
                char *buffContent = (char *)sqlite3_column_text(statement, 1);
                NSString *strContent = [[NSString alloc] initWithUTF8String:buffContent];
                Note *note = [[Note alloc] initWithDate:date content:strContent];
                sqlite3_finalize(statement);
                sqlite3_close(db);
                
                return note;
            }
        }
        sqlite3_finalize(statement);
        sqlite3_close(db);
    }
    return nil;
}

@end
